package com.kehutong.admin.controler;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

import org.coraframework.authz.HasPermission;
import org.coraframework.authz.Subject;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.mvc.ActionResult;
import org.coraframework.mvc.MvcAction;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.JSONResult;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.Objects;

import com.kehutong.admin.entity.Role;
import com.kehutong.admin.entity.User;
import com.kehutong.admin.util.UserUtils;
import com.kehutong.common.entity.Root;
import com.kehutong.common.util.Token;

@MvcAction
@ReqMapping("/admin/sys/user")
public class UserController {

	@Inject
    private JdbcSession jdbcSession;
	
	@ReqMapping("/listByRole")
    public Object listByRole(Token token, JSONObject params, String roleNo) {
		params.put("companyNo", token.getCompanyNo());
    	return jdbcSession.findArray(User.class)
    			.eq(params, "companyNo")
    			.eq("deleted", false)
    			.like("roles", roleNo)
    			.exe();
    }

    @HasPermission("sys:user:view")
    @ReqMapping("/list")
    public ActionResult<String> list(Token token, JSONObject jsonObject) {
    	FindPage<User> find = jdbcSession.findPage(User.class)
    			.eq("deleted", false)
				.eq(jsonObject, "id",  "email", "phone", "wexinId", "officeId")
				.like(jsonObject, "name", "login_name", "mobile");

//		User user = UserUtils.getUser();
		if (Objects.nonEmpty(token.getCompanyNo())) {
			find.eq("companyNo", token.getCompanyNo()).and();
			find.eq(jsonObject, "companyNo");
		} else {
			find.eq(jsonObject, "companyNo");
		}
		
    	Page<User> page = find.order("createTime", "DESC")
				.page(jsonObject)
				.exe();
    	return Result.success(page);
    }
    
    @HasPermission("sys:user:view")
    @ReqMapping("/get")
    public ActionResult<String> getById(JSONObject jsonObject) {
    	User user = Pool.get(User.class, jsonObject.getString("id"));
    	if (user == null || user.isDeleted()) {
    		return Result.error(0, "对象不存在");
    	}

    	return Result.success(user);
    }

    @HasPermission("sys:user:edit")
    @ReqMapping("/save")
    public ActionResult<String> save(JSONObject jsonObject) {
    	String login_name = jsonObject.getString("login_name");
    	User user = jdbcSession.findOne(User.class)
    			.eq("login_name", login_name)
    			.exe();
    	if (user != null) {
    		return Result.error(10301, "会员已存在");
    	} 
    	
    	user = Pool.newInstance(User.class);
    	JSONResult rs = setProperty(user, jsonObject);
    	if (rs.isOk()) {
    		jdbcSession.insert(user);
    	}
    	
    	return rs;
    }
    
    @HasPermission("sys:user:edit")
    @ReqMapping("/update")
    public ActionResult<String> update(JSONObject jsonObject) {
    	User user = Pool.get(User.class, jsonObject.getString("id"));
    	
    	JSONResult rs = setProperty(user, jsonObject);
    	if (rs.isOk()) {
    		jdbcSession.updateById(user);
    	}
    	
        return rs;
    }

    @HasPermission("sys:user:edit")
    @ReqMapping("/changePasswd")
    public ActionResult<String> validatePwd(JSONObject jsonObject) {
    	User user = UserUtils.getUser();
		if (Objects.isNull(user)) {
			return Result.error(2001, "用户不存在");
		}
		
		String oldPassword = jsonObject.getString("oldPassword");
		String newPassword = jsonObject.getString("newPassword");
		if (!user.getPassword().equals(Subject.encrypt(oldPassword))) {
			return Result.error(2001, "修改密码失败，旧密码错误");
		}

		user.setPassword(Subject.encrypt(newPassword));
		jdbcSession.updateById(user);
    			
		return Result.success();
    }
    
 

    @HasPermission("sys:user:edit")
    @ReqMapping("/delete")
    public ActionResult<String> deleteById(JSONObject jsonObject) {
    	User user = jdbcSession.findById(User.class, jsonObject.getString("id"));
    	if (user != null) {
    		user.setDeleted(Boolean.TRUE);
    		jdbcSession.updateById(user);
    	}
    	
        return Result.success();
    }
    
    private JSONResult setProperty(User item, JSONObject jsonObject) {
    	Set<String> roles = getRoles(jsonObject);
    	item.setRoles(roles);
    	if (item.isAdmin() || (item.isAdminRole() && Objects.nonEmpty(item.getCompanyNo()))) {
    		item.setCompanyNo(null);
    		item.setCompanyName(null);
    	} else {
    		item.setCompanyNo(jsonObject.getString("companyNo"));
    		item.setCompanyName(jsonObject.getString("companyName"));
    	}
    	
		String passwd = jsonObject.getString("password");
		if (Objects.isTrimNotEmpty(passwd)) {
			item.setPassword(Subject.encrypt(passwd));
		}
		
		item.setNo(jsonObject.getString("no"));
		item.setName(jsonObject.getString("name"));
		item.setLogin_name(jsonObject.getString("login_name"));
		item.setEmail(jsonObject.getString("email"));
		item.setMobile(jsonObject.getString("mobile"));
		item.setPhone(jsonObject.getString("phone"));
		item.setRemark(jsonObject.getString("remark"));

		return Result.success();
	}
    
	private Set<String> getRoles(JSONObject jsonObject) {
		JSONArray jsonArray = jsonObject.getJSONArray("roles");
		if (Objects.isEmpty(jsonArray)) {
			return new HashSet<>();
		}
		
		Set<String> roleList = new LinkedHashSet<>();
		for (int i = 0; i < jsonArray.size(); i ++) {
			String roleNo = jsonArray.getString(i);
			if (Root.isRoot(roleNo)) {
				roleList.clear();
				roleList.add(roleNo);
				return roleList;
			}
			
			final Role role = Pool.get(Role.class, jsonArray.getString(i));
			if (role != null && !role.isDeleted()) {
				roleList.add(role.getId());
			}
		}
		return roleList;
	}
	
}
